package com.NetWork.Netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import io.netty.util.concurrent.GlobalEventExecutor;


public class Server {
    private static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    private static EventLoopGroup bossGroup;
    private static EventLoopGroup workerGroup;

    public static void StartServer(int port) {
        //创建一个boosGroup来管理 所有的客户端连接
        bossGroup = new NioEventLoopGroup();
        //创建workerGroup来对客户端请求处理
        workerGroup = new NioEventLoopGroup();
        //创建服务端请求引导类，用来加载初始化服务器
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)//指定通道类型
                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .childHandler(new ChannelInitializer<SocketChannel>() { //添加对应的通道处理
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline()
                                .addLast(new ChannelInboundHandlerAdapter() {
                                    @Override
                                    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
                                        channels.add(ctx.channel());
                                    }

                                    @Override
                                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                        channels.writeAndFlush(msg);
                                    }

                                    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
                                        System.out.println(ctx.channel().remoteAddress() + "offLine");
                                    }

                                    @Override
                                    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {  // (3)

                                    }

                                    @Override
                                    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (7)
                                        Channel incoming = ctx.channel();
                                        System.out.println("SimpleChatClient:" + incoming.remoteAddress() + "error");
                                        // 当出现异常就关闭连接
                                        ctx.close();
                                    }

                                });
                    }
                })
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childOption(ChannelOption.TCP_NODELAY, true)
                .childOption(ChannelOption.ALLOCATOR,PooledByteBufAllocator.DEFAULT);
        bootstrap.bind(port);
        System.out.println("Server started on port: " + port);
    }

    public static void stopServer() {

        if (!channels.isEmpty()) {
            channels.close();
        }
        if (bossGroup != null) {
            bossGroup.shutdownGracefully();
        }
        if (workerGroup != null) {
            workerGroup.shutdownGracefully();
        }
    }
}
